package com.tbit.uqbike.client.service.impl;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.tbit.uqbike.client.constant.BrandConstant;
import com.tbit.uqbike.client.constant.RedisConstant;
import com.tbit.uqbike.client.pojo.User;
import com.tbit.uqbike.client.service.CacheService;
import com.tbit.uqbike.client.service.RedisService;
import com.tbit.uqbike.client.service.TokenService;
import com.tbit.uqbike.client.util.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import java.util.Optional;

import static com.tbit.uqbike.client.constant.RedisConstant.TOKEN_PREFIX;
import static com.tbit.uqbike.client.constant.RedisConstant.TOKEN_SEPARATOR;

@Service("tokenService")
public class TokenServiceImpl implements TokenService {
    @Autowired
    private RedisService redisService;

    @Autowired
    private CacheService cacheService;

    /**
     * 默认14天-20160分钟
     */
    private final Integer DEFAULT_EXPIRY_DAYS = 20160;



    @Override
    public User getUser(String token) {
        String usetString = redisService.get(token);
        if (usetString != null) {
            return JSON.parseObject(usetString, User.class);
        }

        return null;
    }

    @Override
    public String storeWithToken(User user) {
        Assert.notNull(user, "user is null");
        Assert.notNull(user.getAccountId(), "accountId is null");
        String token = generateToken(user);

        /**判断用户是否存在*/
        String userKey = generateUserKey(user);
        String tokenOld = redisService.get(userKey);
        if (tokenOld != null) {
            redisService.del(tokenOld);//不可以同时登录
        }

        Integer expiryDays = getExpiryDaysForNoLogin(user.getAccountId());
        /**新加token*/
        String userString = JSON.toJSONString(user);
        redisService.add(token, userString, expiryDays * 60);//14天

        /**用户和token对应关系*/
        redisService.add(userKey, token, expiryDays * 60);

        return token;
    }

    @Override
    public String generateUserKey(User user) {
        Assert.notNull(user, "user is null");
        Assert.notNull(user.getAccountId(), "accountId is null");
        Assert.notNull(user.getUserId(), "userId is null");

        String userKey = new StringBuilder(RedisConstant.REDIS_ACCOUNT_USER)
                .append(TOKEN_SEPARATOR)
                .append(user.getAccountId())
                .append(TOKEN_SEPARATOR)
                .append(user.getUserId())
                .toString();
        return userKey;
    }


    private String generateToken(User user) {
        return new StringBuilder(TOKEN_PREFIX)
                .append(TOKEN_SEPARATOR)
                .append(user.getAccountId())
                .append(TOKEN_SEPARATOR)
                .append(user.getUserId())
                .append(TOKEN_SEPARATOR)
                .append(StringUtil.getUUID())
                .toString();
    }

    /**
     * 获取免登录时间
     * 免登录过期天数 范围在 1-365天,默认14天
     * @param accountId
     */
    private Integer getExpiryDaysForNoLogin(Integer accountId) {
        Integer expireDays = Optional.ofNullable(cacheService.getBrandRemoteConfig(accountId,
                        BrandConstant.NO_LOGIN_EXPIRY_MINUTE))
                .filter(x -> StrUtil.isNotBlank(x.getParamKV()))
                .map(x -> x.getParamKV())
                .filter(x -> x.matches("\\d+"))
                .map(Integer::parseInt)
                .filter(x -> x >= 1 && x <= 525600)
                .orElse(DEFAULT_EXPIRY_DAYS);
        return expireDays;
    }

}  